using System.Reflection;
using AspectCore.DynamicProxy.Parameters;
using Vin.Extension.Aop.Attributes.Parameter;
using Vin.Extension.SqlSugar.Attributes;
using Vin.Extension.SqlSugar.DataExecute;
using Vin.Tool.AspNetCore.Singleton;
using Vin.Tool.Core.AssertCategory;

namespace Vin.Extension.Framework.Aop;

public class VinSugarEncryptParamAttribute<T> : VinBaseParameterInterceptorAttribute
    where T : class, IVinSugarBaseEncryptAdapter
{
    public override async Task Invoke(ParameterAspectContext context, ParameterAspectDelegate next)
    {
        var adapter = VinApp.GetServiceByHttpContext<T>() ?? VinApp.GetService<T>();
        if (adapter == null) throw new System.Exception("加密适配器未注册");

        var parameter = context.Parameter;
        // 判断参数是否是字符串类型
        if (parameter.Value is string value)
        {
            // 加密参数
            parameter.Value = adapter.Encrypt(value);
        }
        else
        {
            // 判断参数是否是对象类型 并加密对象中的指定属性
            if (parameter.Value is { } obj)
            {
                obj.GetType().GetProperties()
                    .Select(m => new
                    {
                        Prop = m,
                        Attr = m.GetCustomAttribute(typeof(VinEncryptAttribute)) as VinEncryptAttribute
                    })
                    .Where(m => m.Attr != null && m.Prop.GetValue(obj) != null &&
                                m.Prop.GetValue(obj)!.ToString().IsNotNullOrWhiteSpace())
                    .ToList()
                    .ForEach(item =>
                    {
                        var tempAdapter = adapter;
                        if (item.Attr!.Adapter != null)
                        {
                            tempAdapter = Activator.CreateInstance(item.Attr.Adapter) as T;
                        }

                        item.Prop.SetValue(obj,
                            tempAdapter!.Encrypt(item.Prop.GetValue(obj)?.ToString() ?? ""));
                    });
            }
        }

        await next(context);
    }
}